<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>JavaScript postObject</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/4.1.1/js/bootstrap.bundle.js"></script>
  </head>
  <style>
    .felx_center {
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
    }
    .p_out {
      width: 100%;
      height: 10px;
      background-color: #d8d4d4;
      border-radius: 4px;
      margin: 10px 0;
    }
    .p_inner {
      background-color: darkcyan;
      height: 10px;
      border-radius: 4px;
      width: 0;
    }
  </style>
  <body>
    <div class="page-header">
      <h1 class="text-center">postObject</h1>
    </div>
    <div class="row felx_center">
      <div class="col-md-5 col-xs-10">
        <div class="panel panel-primary">
          <div class="panel-heading" style="margin-bottom: 20px">1. postObject</div>
          <form>
            <div class="form-group">
              <label>Save as</label>
              <input type="text" class="form-control" id="key1" name="key" placeholder="上传后的文件名称" />
            </div>
            <div class="form-group">
              <label>Select file</label>
              <input type="file" id="file1" name="file" /><br />
            </div>
          </form>
          <div class="form-group">
            <div class="p_out">
              <div id="progress_inner1" class="p_inner"></div>
            </div>
          </div>
          <div class="form-group">
            <input id="upload1" type="button" class="btn btn-primary" id="file-button" value="上传" />
          </div>
        </div>
      </div>
      <div class="col-md-5 col-xs-10">
        <div class="panel panel-primary">
          <div class="panel-heading" style="margin-bottom: 20px">2. postObject By STS</div>
          <form>
            <div class="form-group">
              <label>Save as</label>
              <input type="text" class="form-control" id="key2" name="key" placeholder="上传后的文件名称" />
            </div>
            <div class="form-group">
              <label>Select file</label>
              <input type="file" id="file2" name="file" /><br />
            </div>
          </form>
          <div class="form-group">
            <div class="p_out">
              <div id="progress_inner2" class="p_inner"></div>
            </div>
          </div>
          <div class="form-group">
            <input id="upload2" type="button" class="btn btn-primary" id="file-button" value="上传" />
          </div>
        </div>
      </div>
    </div>
  </body>
  <script type="text/javascript">
    var uploading = {};

    var checkConfig = {
      '#upload1': [
        {
          key: '#key1',
          formDataKey: 'key',
          tip: '请输入文件名称'
        },
        {
          key: '#file1',
          formDataKey: 'file',
          tip: '请选择上传文件'
        }
      ],
      '#upload2': [
        {
          key: '#key2',
          formDataKey: 'key',
          tip: '请输入文件名称'
        },
        {
          key: '#file2',
          formDataKey: 'file',
          tip: '请选择上传文件'
        }
      ]
    };

    function getPostParams(uploadBtnSelector) {
      $.ajax({
        type: 'GET',
        url: 'postObject',
        success: function (data) {
          successCallback(data, '#progress_inner1', uploadBtnSelector);
        },
        error: function (err) {
          uploading[uploadBtnSelector] = false;
          console.log('getPostParams: error');
          if (err.responseJSON) {
            alert(err.responseJSON.message);
          }
        }
      });
    }

    function getPostParamsBySTS(uploadBtnSelector) {
      $.ajax({
        type: 'GET',
        url: 'postObjectBySTS',
        success: function (data) {
          successCallback(data, '#progress_inner2', uploadBtnSelector);
        },
        error: function (err) {
          uploading[uploadBtnSelector] = false;
          if (err.responseJSON) {
            alert(err.responseJSON.message);
          }
        }
      });
    }

    function successCallback(data, p_selector, uploadBtnSelector) {
      var formData = new FormData();
      Object.keys(data.formData).forEach(key => {
        formData.append(key, data.formData[key]);
      });
      formData.append('success_action_status', 200); // 上传成功后返回的status， 如果该域的值未设置或者设置成一个非法值，OSS返回一个空文档和204状态码

      checkConfig[uploadBtnSelector].forEach(item => {
        if (item.formDataKey.startsWith('file')) {
          formData.append(item.formDataKey, $(item.key)[0].files[0]); // 文件或文件内容必须是表单最后一个域
        } else {
          formData.append(item.formDataKey, $(item.key)[0].value);
        }
      });

      $.ajax({
        url: data.url, // 上传的oss的bucket地址
        type: 'post', // post请求方式
        data: formData, // 参数
        cache: false,
        processData: false,
        contentType: false,
        success: function (data, status, xhr) {
          console.log('success---upload');
          uploading[uploadBtnSelector] = false;
        },
        xhr: function () {
          myXhr = $.ajaxSettings.xhr();
          if (myXhr.upload) {
            myXhr.upload.addEventListener(
              'progress',
              progress => {
                progressHandlingFunction(progress, p_selector);
              },
              false
            );
          }
          return myXhr; //xhr对象返回给jQuery使用
        },
        error: function (xhr, status, err) {
          alert('上传失败~');
          uploading[uploadBtnSelector] = false;
        }
      });
    }

    function progressHandlingFunction(p, p_selector) {
      setProgress(p.loaded / p.total, p_selector);
    }

    function setProgress(p, p_selector) {
      $(p_selector)[0].style.width = p * 100 + '%';
    }

    function handleAddEventListener(selector) {
      $(selector).click(function () {
        if (!uploading[selector] && checkInput(checkConfig[selector])) {
          if (selector === '#upload1') {
            console.log('getPostParams: start');
            getPostParams(selector);
          } else {
            getPostParamsBySTS(selector);
          }
          uploading[selector] = true;
        }
      });
    }

    $(window).ready(function () {
      Object.keys(checkConfig).forEach(_ => {
        handleAddEventListener(_);
      });
    });

    function checkInput(_checkConfig) {
      let valid = true;
      for (_ of _checkConfig) {
        if (!$(_.key)[0].value) {
          alert(_.tip);
          valid = false;
          break;
        }
      }
      return valid;
    }
  </script>
</html>
